package cn.ug.member.web.job;

import cn.ug.bean.base.DataTable;
import cn.ug.bean.base.SerializeObject;
import cn.ug.config.RedisGlobalLock;
import cn.ug.enums.RFMLabelEnum;
import cn.ug.feign.ProductOrderService;
import cn.ug.member.mapper.entity.MemberLabel;
import cn.ug.member.mapper.entity.MemberLabelBaseline;
import cn.ug.member.service.MemberLabelService;
import cn.ug.pay.bean.RFMLabelBean;
import cn.ug.util.UF;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.scheduling.annotation.Scheduled;
import org.springframework.stereotype.Component;

import javax.annotation.Resource;
import java.text.SimpleDateFormat;
import java.util.ArrayList;
import java.util.Calendar;
import java.util.List;
import java.util.concurrent.TimeUnit;

import static cn.ug.util.ConstantUtil.*;

@Component
public class CountMemberLabelJobs {
    @Autowired
    private MemberLabelService memberLabelService;
    @Resource
    private RedisGlobalLock redisGlobalLock;
    @Autowired
    private ProductOrderService productOrderService;

    @Scheduled(cron = "0 0 1 1 * ?")
    public void remarkRecount() {

        String key = "CountMemberLabelJobs:remarkRecount:" + UF.getFormatDateTime("yyyy-MM", UF.getDateTime());
        if(!redisGlobalLock.lock(key, 32, TimeUnit.DAYS)) {
            return;
        }

        MemberLabelBaseline labelBaseline = memberLabelService.getLabelBaseline();
        if (labelBaseline != null) {
            labelBaseline.setStatus(2);
            memberLabelService.save(labelBaseline);
        }
    }

    @Scheduled(cron = "0 0 3 * * ?")
    //@Scheduled(cron = "0 01 11 * * ?")
    public void recountResult() {

        String key = "CountMemberLabelJobs:recountResult:" + UF.getFormatDateTime("yyyy-MM-dd HH", UF.getDateTime());
        if(!redisGlobalLock.lock(key, 1, TimeUnit.DAYS)) {
            return;
        }

        MemberLabelBaseline labelBaseline = memberLabelService.getLabelBaseline();
        if (labelBaseline != null && labelBaseline.getRfmDays() > 0 && labelBaseline.getStatus() == 2) {
            SimpleDateFormat dateFormat = new SimpleDateFormat(NORMAL_DATE_FORMAT);
            Calendar calendar = Calendar.getInstance();
            String endDate = dateFormat.format(calendar.getTime())+MIN_TIME;
            calendar.add(Calendar.DAY_OF_YEAR, -labelBaseline.getRfmDays());
            String startDate = dateFormat.format(calendar.getTime())+MIN_TIME;
            int pageSize = 1000;
            int pageNum = 1;
            int errorNum = 0;
            while(true) {
                if (errorNum > 30) {
                    break;
                }
                try {
                    Thread.sleep(3000);
                    SerializeObject<DataTable<RFMLabelBean>> result = productOrderService.list(pageNum, pageSize, startDate, endDate);
                    if (result != null && result.getData() != null && result.getData().getDataList() != null && result.getData().getDataList().size() > 0) {
                        List<RFMLabelBean> beans = result.getData().getDataList();
                        List<MemberLabel> labels = new ArrayList<MemberLabel>();
                        for (RFMLabelBean bean : beans) {
                            MemberLabel label = new MemberLabel();
                            label.setRvalue(bean.getR());
                            label.setFvalue(bean.getF());
                            label.setMvalue(bean.getM());
                            label.setMemberId(bean.getMemberId());
                            label.setRecentTradeTime(bean.getRecentTradeTime());
                            if (bean.getR() < labelBaseline.getRvalue() && bean.getF() > labelBaseline.getFvalue() && bean.getM().doubleValue() > labelBaseline.getMvalue()) {
                                label.setRfm1(RFMLabelEnum.LABEL1.getScore());
                                label.setRfmCategory1(RFMLabelEnum.LABEL1.getMsg());
                            }
                            if (bean.getR() < labelBaseline.getRvalue() && bean.getF() <= labelBaseline.getFvalue() && bean.getM().doubleValue() > labelBaseline.getMvalue()) {
                                label.setRfm1(RFMLabelEnum.LABEL2.getScore());
                                label.setRfmCategory1(RFMLabelEnum.LABEL2.getMsg());
                            }
                            if (bean.getR() >= labelBaseline.getRvalue() && bean.getF() > labelBaseline.getFvalue() && bean.getM().doubleValue() > labelBaseline.getMvalue()) {
                                label.setRfm1(RFMLabelEnum.LABEL3.getScore());
                                label.setRfmCategory1(RFMLabelEnum.LABEL3.getMsg());
                            }
                            if (bean.getR() >= labelBaseline.getRvalue() && bean.getF() <= labelBaseline.getFvalue() && bean.getM().doubleValue() > labelBaseline.getMvalue()) {
                                label.setRfm1(RFMLabelEnum.LABEL4.getScore());
                                label.setRfmCategory1(RFMLabelEnum.LABEL4.getMsg());
                            }
                            if (bean.getR() < labelBaseline.getRvalue() && bean.getF() > labelBaseline.getFvalue() && bean.getM().doubleValue() <= labelBaseline.getMvalue()) {
                                label.setRfm1(RFMLabelEnum.LABEL5.getScore());
                                label.setRfmCategory1(RFMLabelEnum.LABEL5.getMsg());
                            }
                            if (bean.getR() < labelBaseline.getRvalue() && bean.getF() <= labelBaseline.getFvalue() && bean.getM().doubleValue() <= labelBaseline.getMvalue()) {
                                label.setRfm1(RFMLabelEnum.LABEL6.getScore());
                                label.setRfmCategory1(RFMLabelEnum.LABEL6.getMsg());
                            }
                            if (bean.getR() >= labelBaseline.getRvalue() && bean.getF() > labelBaseline.getFvalue() && bean.getM().doubleValue() <= labelBaseline.getMvalue()) {
                                label.setRfm1(RFMLabelEnum.LABEL7.getScore());
                                label.setRfmCategory1(RFMLabelEnum.LABEL7.getMsg());
                            }
                            if (bean.getR() >= labelBaseline.getRvalue() && bean.getF() <= labelBaseline.getFvalue() && bean.getM().doubleValue() <= labelBaseline.getMvalue()) {
                                label.setRfm1(RFMLabelEnum.LABEL8.getScore());
                                label.setRfmCategory1(RFMLabelEnum.LABEL8.getMsg());
                            }
                            labels.add(label);
                        }
                        if (labels != null && labels.size() > 0) {
                            memberLabelService.updateInBatch(labels);
                        }
                        pageNum++;
                    } else {
                        break;
                    }
                } catch (Exception e) {
                    e.printStackTrace();
                    errorNum++;
                    continue;
                }
            }
            MemberLabelBaseline rfmAvg = memberLabelService.getRFMAvg();
            if (rfmAvg != null) {
                if (rfmAvg.getRavg() != null) {
                    labelBaseline.setRavg(rfmAvg.getRavg());
                }
                if (rfmAvg.getFavg() != null) {
                    labelBaseline.setFavg(rfmAvg.getFavg());
                }
                if (rfmAvg.getMavg() != null) {
                    labelBaseline.setMavg(rfmAvg.getMavg());
                }
            }
            labelBaseline.setCountingDate(dateFormat.format(Calendar.getInstance().getTime()));
            labelBaseline.setStatus(1);
            memberLabelService.save(labelBaseline);
        }
    }
}
